//    Copyright (C) Kherty.  All rights reserved.
using System.Diagnostics;
using System.Diagnostics.Contracts;
using OpenLS.Spreadsheet.Internals;

namespace OpenLS.Spreadsheet
{
    class GroupBuilderStack<T> where T: Dimension
    {

        public GroupBuilderStack(RootGroup rootGroup, GroupFactory groupFactory)
        {
            Current = new RootGroupBuilder(rootGroup, groupFactory);
        }

        private GroupBuilder _current;
        private GroupBuilder Current
        {
            get { return _current; }
            set { _current = value; }
        }

        internal void ApplyOutlineLevel(T dimension, T lastDimension,  byte outlineLevel, bool isVisible,  bool forceCollapse)
        {
            Contract.Requires(dimension != null);
            Contract.Requires(lastDimension != null);
            if (outlineLevel == 0 && !forceCollapse)
                return;
            if (forceCollapse && Current is ChildGroupBuilder&& outlineLevel <= Current.Depth)
            {
                var builder = (ChildGroupBuilder)Current;
                builder.Collapse();
                builder.Close(lastDimension.GetPrevious());
               //\\ if (!isVisible)
                Current = builder.Parent;
                if (Current is ChildGroupBuilder)
                {
                    ((ChildGroupBuilder)Current).SetCurrent(dimension);
                }
                return;
            }
            if (Current.Depth == outlineLevel)
            {
                if (!(Current is ChildGroupBuilder))
                    return;
                var builder = (ChildGroupBuilder) Current;
                if (dimension.Index > builder.Current.Index + 1)
                {
                    builder.Close(builder.Current);
                    Current = builder.Parent;
                }
                else
                {
                    builder.SetCurrent (dimension);
                    return;                    
                }
            }
            while (outlineLevel > Current.Depth)
            {
                Current = new ChildGroupBuilder(Current, dimension);
            }
            while (outlineLevel < Current.Depth)
            {
                var builder = (ChildGroupBuilder) Current;
                T previousDimension = dimension;
                if (dimension.Index > 0)
                    previousDimension = (T) dimension.GetPrevious();
                if (forceCollapse)
                    builder.Collapse();
                else
                {
                    builder.Close(previousDimension);
                }
                Current = builder.Parent;
            }
        }

        internal void Close()
        {
            while (Current.Depth > 0)
            {
                var builder = (ChildGroupBuilder)Current;
                builder.Close(builder.Current);
                Current = builder.Parent;
            }
            if (Current.Group == null)
                return;
            Current.Apply();
        }

        
    }
}
